package xyz.riceball.develop.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.riceball.develop.entity.po.DictionaryPO;
import xyz.riceball.develop.mapper.DictionaryMapper;
import xyz.riceball.develop.service.DictionaryService;
import xyz.riceball.framework.core.bean.ApiR;
import xyz.riceball.framework.core.bean.ApiRc;
import xyz.riceball.framework.core.context.UserContext;
import xyz.riceball.framework.core.exception.RiceBallBizWarnException;
import xyz.riceball.framework.core.util.BeanUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 字典表(Dictionary)表服务实现类
 *
 * @author xiaovcloud
 * @since 2022-04-26 13:11:31
 */
@Service("dictionaryService")
public class DictionaryServiceImpl extends ServiceImpl<DictionaryMapper, DictionaryPO> implements DictionaryService {

    @Override
    public Page<DictionaryPO> pageCategory(Page<DictionaryPO> page, DictionaryPO dictionary) {
        LambdaQueryWrapper<DictionaryPO> wrapper = Wrappers.<DictionaryPO>lambdaQuery();
        wrapper.isNull(DictionaryPO::getValue);
        return this.getBaseMapper().selectPage(page, wrapper);
    }

    @Override
    public Page<DictionaryPO> pageItem(Page<DictionaryPO> page,DictionaryPO dictionaryPO) {
        LambdaQueryWrapper<DictionaryPO> wrapper = Wrappers.<DictionaryPO>lambdaQuery();
        wrapper.isNotNull(DictionaryPO::getValue);
        if (StrUtil.isNotEmpty(dictionaryPO.getCode())){
            wrapper.eq(DictionaryPO::getCode,dictionaryPO.getCode());
        }
        return this.getBaseMapper().selectPage(page, wrapper);
    }

    @Override
    public ApiR<DictionaryPO> addCategory(DictionaryPO dictionary) {
        checkDictionaryBeforeDb(dictionary);

        dictionary.setValue(null);
        BeanUtils.buildAutoField(dictionary, true, UserContext.getUserId());
        int insert = getBaseMapper().insert(dictionary);

        return ApiR.msgData(insert == 1, "新增字典成功！", "新增字典失败！", dictionary);
    }

    /**
     * 新增字典类别前的检测
     *
     * @param dictionary
     */
    private void checkDictionaryBeforeDb(DictionaryPO dictionary) {
        List<DictionaryPO> dictionaryList;
        if (StrUtil.isEmpty(dictionary.getId())) {
            //新增
            LambdaQueryWrapper<DictionaryPO> wrapperCode = Wrappers.lambdaQuery();
            wrapperCode.eq(DictionaryPO::getCode, dictionary.getCode())
                    .isNull(DictionaryPO::getValue);

            dictionaryList = getBaseMapper().selectList(wrapperCode);
            if (dictionaryList.size() > 0) {
                throw new RiceBallBizWarnException("编码重复");
            }

            LambdaQueryWrapper<DictionaryPO> wrapperName = Wrappers.lambdaQuery();
            wrapperName.eq(DictionaryPO::getOption, dictionary.getOption())
                    .isNull(DictionaryPO::getValue);
            dictionaryList = getBaseMapper().selectList(wrapperCode);
            if (dictionaryList.size() > 0) {
                throw new RiceBallBizWarnException("字典类别重复");
            }
        } else {
            //修改
            LambdaQueryWrapper<DictionaryPO> wrapperCode = Wrappers.lambdaQuery();
            wrapperCode.eq(DictionaryPO::getCode, dictionary.getCode())
                    .isNull(DictionaryPO::getValue);
            dictionaryList = getBaseMapper().selectList(wrapperCode);
            if (dictionaryList.size() == 1) {
                if (!dictionaryList.get(0).getId().equals(dictionary.getId())) {
                    throw new RiceBallBizWarnException("编码重复");
                }
            } else if (dictionaryList.size() > 1) {
                throw new RiceBallBizWarnException("编码重复");
            }

            LambdaQueryWrapper<DictionaryPO> wrapperName = Wrappers.lambdaQuery();
            wrapperName.eq(DictionaryPO::getOption, dictionary.getOption())
                    .isNull(DictionaryPO::getValue);
            dictionaryList = getBaseMapper().selectList(wrapperCode);
            if (dictionaryList.size() > 1) {
                throw new RiceBallBizWarnException("名称重复");
            } else if (dictionaryList.size() == 1) {
                if (!dictionaryList.get(0).getId().equals(dictionary.getId())) {
                    throw new RiceBallBizWarnException("名称重复");
                }
            }
        }
    }

    @Override
    public boolean edit(DictionaryPO dictionary) {
        checkDictionaryBeforeDb(dictionary);

        DictionaryPO dictionaryPO = getBaseMapper().selectById(dictionary.getId());
        BeanUtils.copyWithoutNull(dictionaryPO, dictionary);
        BeanUtils.buildAutoField(dictionaryPO, false, UserContext.getUserId());
        int update = getBaseMapper().updateById(dictionaryPO);
        return update == 1;
    }

    @Override
    public ApiR<DictionaryPO> addItem(DictionaryPO dictionary) {
        checkDictionaryItemBeforeAdd(dictionary);

        BeanUtils.buildAutoField(dictionary, true, UserContext.getUserId());
        int insert = getBaseMapper().insert(dictionary);
        return ApiR.msgData(insert == 1, "新增字典成功！", "新增字典失败！", dictionary);
    }

    /**
     * 字典项新增前的校验
     *
     * @param dictionary
     */
    private void checkDictionaryItemBeforeAdd(DictionaryPO dictionary) {
        //新增
        LambdaQueryWrapper<DictionaryPO> wrapperValue = Wrappers.lambdaQuery();
        wrapperValue.eq(DictionaryPO::getCode, dictionary.getCode())
                .eq(DictionaryPO::getValue, dictionary.getValue());

        List<DictionaryPO> dictionaryList = getBaseMapper().selectList(wrapperValue);
        if (dictionaryList.size() > 0) {
            throw new RiceBallBizWarnException("值重复！");
        }

        LambdaQueryWrapper<DictionaryPO> wrapperName = Wrappers.lambdaQuery();
        wrapperName.eq(DictionaryPO::getCode, dictionary.getCode())
                .eq(DictionaryPO::getOption, dictionary.getOption());
        dictionaryList = getBaseMapper().selectList(wrapperName);
        if (dictionaryList.size() > 0) {
            throw new RiceBallBizWarnException("名称重复！");
        }

    }

    @Override
    public boolean editItem(DictionaryPO dictionary) {
        checkDictionaryItemBeforeEdit(dictionary);

        DictionaryPO dictionaryPO = getBaseMapper().selectById(dictionary.getId());
        BeanUtils.copyWithoutNull(dictionaryPO, dictionary);
        BeanUtils.buildAutoField(dictionaryPO, false, UserContext.getUserId());
        int update = getBaseMapper().updateById(dictionaryPO);
        return update == 1;
    }

    /**
     * 修改字典类别前的检测
     *
     * @param dictionary
     */
    private void checkDictionaryItemBeforeEdit(DictionaryPO dictionary) {
        LambdaQueryWrapper<DictionaryPO> wrapperValue = Wrappers.lambdaQuery();
        wrapperValue.eq(DictionaryPO::getCode, dictionary.getCode())
                .eq(DictionaryPO::getValue, dictionary.getValue());

        List<DictionaryPO> dictionaryList = getBaseMapper().selectList(wrapperValue);
        if (dictionaryList.size() > 2) {
            throw new RiceBallBizWarnException("值重复!");
        } else if (dictionaryList.size() == 1) {
            if (!dictionaryList.get(0).getId().equals(dictionary.getId())) {
                throw new RiceBallBizWarnException("值重复!");
            }
        }

        LambdaQueryWrapper<DictionaryPO> wrapperName = Wrappers.lambdaQuery();
        wrapperName.eq(DictionaryPO::getCode, dictionary.getCode()).eq(DictionaryPO::getOption, dictionary.getOption());
        dictionaryList = getBaseMapper().selectList(wrapperName);
        if (dictionaryList.size() > 1) {
            throw new RiceBallBizWarnException("名称重复！");
        } else if (dictionaryList.size() == 1) {
            if (!dictionaryList.get(0).getId().equals(dictionary.getId())) {
                throw new RiceBallBizWarnException("名称重复!");
            }
        }

    }

    @Override
    public ApiRc<Void> delete(List<String> codeList) {
        ApiRc<Void> delete = ApiRc.buildResultCount(codeList.size());
        for (String code : codeList) {
            try {
                LambdaQueryWrapper<DictionaryPO> wrappers = Wrappers.lambdaQuery();
                wrappers.eq(DictionaryPO::getCode, code);
                int count = getBaseMapper().delete(wrappers);
                if (count > 0) {
                    delete.success();
                }
            } catch (Exception e) {
                log.error("删除字典分类失败！", e);
            }
        }
        return ApiRc.getResult(delete);
    }

    @Override
    public ApiRc<Void> deleteItem(List<String> ids) {
        int delete = getBaseMapper().deleteBatchIds(ids);
        ApiRc<Void> result = ApiRc.buildResultCount(ids.size());
        result.setTotalCount((long) ids.size());
        result.setSuccessCount((long) delete);
        return ApiRc.getResult(result);
    }

    @Override
    public List<List<DictionaryPO>> selectItem(List<String> codes) {
        List<List<DictionaryPO>> results = new ArrayList<>();
        for (String code : codes) {
            LambdaQueryWrapper<DictionaryPO> wrappers = Wrappers.lambdaQuery();
            wrappers.eq(DictionaryPO::getCode, code)
                    .isNotNull(DictionaryPO::getValue);
            List<DictionaryPO> dictionaryPOS = getBaseMapper().selectList(wrappers);
            results.add(dictionaryPOS);
        }
        return results;
    }

    @Override
    public List<DictionaryPO> selectItem(String code, List<String> values) {
        LambdaQueryWrapper<DictionaryPO> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(DictionaryPO::getCode, code)
                .in(DictionaryPO::getValue, values);
        return getBaseMapper().selectList(wrapper);
    }
}

